#include <opencv2/opencv.hpp>
#include <unistd.h>
#include "./include/DxImageProc.h"
#include "./include/GxIAPI.h"

#define ACQ_BUFFER_NUM          5               ///< Acquisition Buffer Qty.
#define ACQ_TRANSFER_SIZE       (64 * 1024)     ///< Size of data transfer block
#define ACQ_TRANSFER_NUMBER_URB 64              ///< Qty. of data transfer block

typedef struct WH
{
    int64_t Width_MAX;
    int64_t Height_MAX;

    WH()
    {
        Width_MAX = 640;
        Height_MAX = 480;
    }

}WH;

typedef struct Roi
{
    int64_t m_i64Width;
    int64_t m_i64Height;
    int64_t m_i64OffsetX;
    int64_t m_i64OffsetY;

    Roi()
    {
        m_i64Width = 560;
        m_i64Height = 420;
        m_i64OffsetX = 80;
        m_i64OffsetY = 60;
    }
}Roi;

typedef struct WhiteBalance
{
    bool m_bWhiteBalance;
    GX_AWB_LAMP_HOUSE_ENTRY lightSource;
    WhiteBalance()
    {
        m_bWhiteBalance = false;
        lightSource = GX_AWB_LAMP_HOUSE_ADAPTIVE;
    }
}WhiteBalance;

typedef struct ExposureGain
{

    bool                 m_bAutoExposure;               ///< Exposure is auto mode or not
    bool                 m_bAutoGain;                   ///< Gain is auto mode or not

    double               m_dExposureTime;               ///< Exposure Time
    double               m_dAutoExposureTimeMax;        ///< Maximum exposure time when using AutoExporsureTime mode
    double               m_dAutoExposureTimeMin;        ///< Minimum exposure time when using AutoExporsureTime mode

    double               m_dGain;                       ///< Gain
    double               m_dAutoGainMax;                ///< Maximum gain when using AutoGain mode
    double               m_dAutoGainMin;                ///< Minimum gain when using AutoGain mode

    int64_t              m_i64GrayValue;                ///< Expected gray value

    ///Default value
    ExposureGain()
    {
        m_bAutoExposure = true;              ///< Exposure is auto mode or not
        m_bAutoGain = true;                  ///< Gain is auto mode or not

        m_dExposureTime = 2000;               ///< 2000us Exposure Time
        m_dAutoExposureTimeMax = 10000;        ///< 5000us Maximum exposure time when using AutoExporsureTime mode
        m_dAutoExposureTimeMin = 500;        ///< 1000us Minimum exposure time when using AutoExporsureTime mode

        m_dGain = 6;                          ///< Gain (Maxium 16dB)
        m_dAutoGainMax = 10;                   ///< Maximum gain when using AutoGain mode
        m_dAutoGainMin = 5;                   ///< Minimum gain when using AutoGain mode

        m_i64GrayValue = 200;                 ///< Expected gray value
    }
}ExposureGain;

class GxCamera
{
public:
    GxCamera();
    ~GxCamera();

    GX_STATUS initLib();

    GX_STATUS OpenDevice();

    GX_STATUS AcquisitionStart();

    void setExposureGainParam( bool AutoExposure,
                               bool AutoGain,
                               double ExposureTime,
                               double AutoExposureTimeMin,
                               double AutoExposureTimeMax,
                               double Gain,
                               double AutoGainMin,
                               double AutoGainMax,
                               int64_t GrayValue);

    void setRoiParam( int64_t Width,
                      int64_t Height,
                      int64_t OffsetX,
                      int64_t OffsetY);

    void setWhiteBalanceParam( bool WhiteBalanceOn,
                               GX_AWB_LAMP_HOUSE_ENTRY lightSource);

    void setWidthHeightParam( int64_t m_Width, int64_t m_Height);

private:

    GX_STATUS setRoi();

    GX_STATUS setWhiteBalance();

    GX_STATUS setExposureGain();

    GX_STATUS setWidthHeight();

private:

    GX_DEV_HANDLE g_hDevice;
    char* g_pDeviceSN;

    ExposureGain exposure_gain;
    Roi roi;
    WhiteBalance white_balance;
    WH width_height;
};
